package cn.iocoder.yudao.module.train.controller.wechat.order;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.infra.service.config.ConfigService;
import cn.iocoder.yudao.module.train.controller.admin.coursegroup.vo.CourseGroupRespVO;
import cn.iocoder.yudao.module.train.controller.admin.order.vo.OrderPageReqVO;
import cn.iocoder.yudao.module.train.controller.admin.order.vo.OrderSaveReqVO;
import cn.iocoder.yudao.module.train.controller.admin.payrefundorder.vo.PayRefundOrderRespVO;
import cn.iocoder.yudao.module.train.controller.admin.student.vo.StudentSaveReqVO;
import cn.iocoder.yudao.module.train.controller.admin.wxuser.vo.WxUserRespVO;
import cn.iocoder.yudao.module.train.controller.admin.wxuser.vo.WxUserSaveReqVO;
import cn.iocoder.yudao.module.train.controller.wechat.login.vo.WxUsersLoginRespVO;
import cn.iocoder.yudao.module.train.dal.dataobject.WxUser.WxUserDO;
import cn.iocoder.yudao.module.train.dal.dataobject.connectDTO.OrdersDTO;
import cn.iocoder.yudao.module.train.dal.dataobject.connectDTO.StudentUserDTO;
import cn.iocoder.yudao.module.train.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.train.dal.dataobject.trade.TradeDO;
import cn.iocoder.yudao.module.train.service.order.OrderService;
import cn.iocoder.yudao.module.train.service.student.StudentService;
import cn.iocoder.yudao.module.train.service.trade.TradeService;
import cn.iocoder.yudao.module.train.service.wxUser.WxUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.MapUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.GET;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.train.enums.ErrorCodeConstants.STUDENT_NOT_EXISTS;
import static cn.iocoder.yudao.module.train.enums.ErrorCodeConstants.WX_USER_NOT_EXISTS;
import static cn.iocoder.yudao.module.train.utils.OrderUtils.*;
import static com.baomidou.mybatisplus.core.toolkit.IdWorker.getId;

@Tag(name = "小程序接口 - 订单记录")
@RestController
@RequestMapping("/wechat-api/order")
public class WechatOrderController {
    @Resource
    private OrderService orderService;

    @Resource
    private WxUserService wxUserService;

    @Resource
    private StudentService studentService;

    @Resource
    private TradeService tradeService;

    @Resource
    private ConfigService configService;

    @GetMapping("/list")
    @Operation(summary = "用户订单列表")
    @ApiAccessLog(operateType = GET)
    public CommonResult<List<OrdersDTO>> listOrders(OrderPageReqVO reqVO) {
        if (reqVO.getStatus() != null) {
            return success(BeanUtils.toBean(orderService.getOrderListByWxUserId(reqVO.getWxUserId(), reqVO.getStatus()), OrdersDTO.class));
        } else  {
            return success(BeanUtils.toBean(orderService.getOrderListByWxUserId(reqVO.getWxUserId()), OrdersDTO.class));
        }
    }

    @GetMapping("/get")
    @Operation(summary = "用户订单详情")
    @ApiAccessLog(operateType = GET)
    public CommonResult<OrdersDTO> getOrderDetail(Integer orderId) {
        return success(orderService.getOrder(orderId));

    }

    /**
     * 创建订单
     *
     * @return
     */
    @PostMapping("/create")
    @Operation(summary = "创建订单")
    @Transactional
    public CommonResult<Integer> create(@RequestBody OrderSaveReqVO orderSaveReqVO) {
        Long wxUserId = orderSaveReqVO.getWxUserId();
        WxUserDO trWxUser = wxUserService.getWxUser(wxUserId);
        if (trWxUser == null) {
            return error(WX_USER_NOT_EXISTS);
        }

        if (orderSaveReqVO.getStudentId() == null) {
            StudentUserDTO studentByUserId = studentService.getStudentByUserId(wxUserId);
            if (studentByUserId != null) {
                orderSaveReqVO.setStudentId(studentByUserId.getId());
                } else {
                return error(STUDENT_NOT_EXISTS);
                }
        }
        if (orderSaveReqVO.getCommodityId() == null && orderSaveReqVO.getLevelId() == null) {
            return error(1000_0_1,"参数错误");
        }

        if (orderSaveReqVO.getCommodityId() != null && orderSaveReqVO.getLevelId() != null) {
            return error(1000_0_1,"参数错误");
        }
        Long commodityId = orderSaveReqVO.getCommodityId();
        OrderPageReqVO orderPageReqVO = new OrderPageReqVO();
        orderPageReqVO.setCommodityId(commodityId);
        orderPageReqVO.setStudentId(orderSaveReqVO.getStudentId());
        orderPageReqVO.setStatus(1);
        List<OrderDO> orderList = orderService.getOrderList(orderPageReqVO);
        if (orderList != null && !orderList.isEmpty()) {
            return error(1000_0_2,"学生已注册该课程");
            }

        if (orderSaveReqVO.getCommodityId() != null) {
            orderSaveReqVO.setOrderType(0);
        }
        if (orderSaveReqVO.getLevelId() != null) {
            orderSaveReqVO.setOrderType(1);
        }

        //生成订单号
        String orderSn = generateOrderSn(wxUserId);
        orderSaveReqVO.setOrderSn(orderSn);

        //生成交易单
        TradeDO trTrade = createTrade(orderSaveReqVO.getWxUserId(), orderSaveReqVO.getSalePrice());
        tradeService.createTrade(trTrade);
        orderSaveReqVO.setTradeSn(trTrade.getTradeSn());

        //创建订单
        return success(orderService.createOrder(orderSaveReqVO));
    }


    /**
     * 主动关闭订单
     */
    @PostMapping("/close")
    @Operation(summary = "主动关闭订单")
    public CommonResult<Boolean> close(@RequestBody Map<String, Object> params) {
        try {
            Long orderId = MapUtils.getLong(params, "orderId");
            if (orderId == null) {
                return error(1000_0_3,"orderId不能为空");
            }
// todo           wxPayService.closePartnerOrderV3(String.valueOf(orderId));
            TradeDO trOrder = tradeService.getTrade(orderId);
            if (trOrder == null) {
                return error(1000_0_4,"订单不存在");
            }
            trOrder.setStatus(4);
            tradeService.updateTrade(trOrder);
            TradeDO trTrade = tradeService.getTradeByTradeSn(trOrder.getTradeSn());
            if (trTrade == null) {
                return error(1000_0_5,"交易单单不存在");
            }
            trTrade.setStatus(4);
            tradeService.updateTrade(trTrade);
            return success(true);
        } catch (Exception e) {
            e.printStackTrace();
            return error(1000_0_6,e.getMessage());
        }
    }

    /**
     * 退款
     *
     * @return
     */
    @PostMapping("/refund")
    @Operation(summary = "退款")
    public CommonResult<Object> refund(@RequestBody OrderSaveReqVO orderSaveReqVO) {
        try {
            Long wxUserId = orderSaveReqVO.getWxUserId();
            if (wxUserId == null) {
                return error(1000_0_7,"wxUserId不能为空");
            }
            Integer orderId = orderSaveReqVO.getId();
            if (orderId == null) {
                return error(1000_0_3,"orderId不能为空");
            }
            // TrOrder.salePrice
            BigDecimal refundAmount = orderSaveReqVO.getRefundAmount();
            if (refundAmount == null) {
                return error(1000_0_8,"退款金额不能为空");
            }

            OrderDO order = orderService.getOrder((orderId));
            if (order == null) {
                return error(1000_0_9,"订单不存在");
            }
            TradeDO trTrade = tradeService.getTradeByTradeSn(order.getTradeSn());
            if (trTrade == null) {
                return error(1000_0_10,"交易单不存在");
            }
            PayRefundOrderRespVO trPayRefundOrder = createRefundOrder(orderSaveReqVO, order.getTradeSn());

            order.setStatus(2);
            order.setUpdater("wxUserId：" + orderSaveReqVO.getWxUserId());
            orderService.updateOrder(order);

            trTrade.setStatus(2);
            trTrade.setUpdater("wxUserId：" + orderSaveReqVO.getWxUserId());
            tradeService.updateTrade(trTrade);
            return success(trPayRefundOrder);
        } catch (Exception e) {
            e.printStackTrace();
            return error(1000_0_11,e.getMessage());
        }
    }

    /**
     * 获取expire
     */
    @PostMapping("/getExpire")
    @Operation(summary = "getExpire")
    public CommonResult<Long> getExpire() {
        Long expire = Long.valueOf(configService.getConfigByKey("tr.pay.expire").getValue());
        return success(expire,"操作成功");
    }

}
